List Comprehensions

List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.

Consider the example of creating a list of squares of numbers from 1 to 9. Normally it can be done as:


In [ ]:
squares = []
for x in range(10):
     squares.append(x**2)

print (squares)

With list comprehensions it can be done as:


In [ ]:
squares = [x**2 for x in range(10)]
print (squares)

Another example:

Suppose for the given inputs:

cities = ['Chicago', 'Detroit', 'Atlanta']
airports = ['ORD', 'DTW', 'ATL']
We want this output:
output = [('Chicago', 'ORD'), ('Detroit', 'DTW'), ('Atlanta', 'ATL')]


In [ ]:
cities = ['Chicago', 'Detroit', 'Atlanta']
airports = ['ORD', 'DTW', 'ATL']

output = [(cities[i], airports[i]) for i in range(3)]

If-Else in List Comprehension


In [ ]:
[x*2 for x in range(10) if x%2 == 0]

In [ ]:
[x*2 if x%2 == 0 else x for x in range(10)]

A more complicated example:


In [ ]:
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

Which loop is being executed first??

Transpose a matrix:


In [ ]:
matrix = [
     [1, 2, 3, 4],
     [5, 6, 7, 8],
     [9, 10, 11, 12],
    ]
[[row[i] for row in matrix] for i in range(4)]

Input:

tests = [('foo', ['a', 'b', 'c']), ('bar', ['d', 'e', 'f'])]

We want

['a', 'b', 'c', 'd', 'e', 'f']

Wrong:


In [ ]:
new_list = [x for x in t[1] for t in tests]

Expanding this would be like:

new_list = []
for x in t[1]:
    for t in tests:
        new_list.append(x)

print (new_list) </pre></code>

But this throws an error.

Correct Way to do:


In [ ]:
new_list = [x for t in tests for x in t[1]]
print (new_list)